package com.company.anr.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.URL;
import java.nio.file.*;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.stream.Collectors;

public class FileUtils {

  private static final Logger logger = LoggerFactory.getLogger(FileUtils.class);

  /**
   * 安全删除文件或目录
   * 
   * @param path 要删除的路径
   */
  public static void safeDelete(Path path) {
    try {
      if (Files.exists(path)) {
        if (Files.isDirectory(path)) {
          deleteDirectoryRecursively(path);
          logger.info("已删除目录: {}", path);
        } else {
          Files.delete(path);
          logger.info("已删除文件: {}", path);
        }
      }
    } catch (IOException e) {
      logger.error("删除 {} 时出错: {}", path, e.getMessage());
    }
  }

  /**
   * 递归删除目录
   * 
   * @param directory 要删除的目录
   * @throws IOException IO异常
   */
  private static void deleteDirectoryRecursively(Path directory) throws IOException {
    if (Files.exists(directory)) {
      Files.walk(directory)
          .sorted((a, b) -> b.compareTo(a)) // 反向排序，先删除文件再删除目录
          .forEach(path -> {
            try {
              Files.delete(path);
            } catch (IOException e) {
              logger.warn("删除文件失败: {}, 错误: {}", path, e.getMessage());
            }
          });
    }
  }

  /**
   * 等待文件出现在指定目录
   * 
   * @param directory      目录路径
   * @param filename       文件名
   * @param timeoutSeconds 超时时间（秒）
   * @return 文件路径，如果超时则返回null
   */
  public static Path waitForFile(Path directory, String filename, int timeoutSeconds) {
    Instant start = Instant.now();
    Duration timeout = Duration.ofSeconds(timeoutSeconds);
    int checkCount = 0;

    logger.info("开始等待文件: {} 在目录: {}", filename, directory);

    while (Duration.between(start, Instant.now()).compareTo(timeout) < 0) {
      try {
        checkCount++;
        Path filePath = directory.resolve(filename);
        if (Files.exists(filePath)) {
          logger.info("文件已出现: {}", filePath);
          return filePath;
        }

        // 检查是否有相似的文件名（处理下载文件名变化的情况）
        List<Path> matchingFiles = Files.list(directory)
            .filter(path -> path.getFileName().toString().contains(filename.replaceAll("\\.[^.]+$", "")))
            .collect(Collectors.toList());

        if (!matchingFiles.isEmpty()) {
          Path foundFile = matchingFiles.get(0);
          logger.info("找到相似文件: {}", foundFile);
          return foundFile;
        }

        // 每10次检查输出一次目录内容
        if (checkCount % 10 == 0) {
          logger.info("第{}次检查，当前目录内容:", checkCount);
          try {
            Files.list(directory).forEach(path -> logger.info("  - {}", path.getFileName()));
          } catch (IOException e) {
            logger.warn("无法列出目录内容: {}", e.getMessage());
          }
        }

        Thread.sleep(1000); // 等待1秒
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        logger.error("等待文件时被中断: {}", e.getMessage());
        return null;
      } catch (IOException e) {
        logger.error("等待文件时出错: {}", e.getMessage());
        return null;
      }
    }

    logger.warn("等待文件超时: {} 在目录 {}", filename, directory);
    return null;
  }

  /**
   * 从URL中提取文件名
   * 
   * @param urlString URL字符串
   * @return 文件名
   */
  public static String extractFilenameFromUrl(String urlString) {
    try {
      URL url = new URL(urlString);
      String path = url.getPath();
      String filename = path.substring(path.lastIndexOf('/') + 1);

      // 移除查询参数
      if (filename.contains("?")) {
        filename = filename.substring(0, filename.indexOf("?"));
      }

      return filename;
    } catch (Exception e) {
      logger.error("解析URL失败: {}, 错误: {}", urlString, e.getMessage());
      return "unknown_file";
    }
  }

  /**
   * 创建目录（如果不存在）
   * 
   * @param path 目录路径
   * @return 是否创建成功
   */
  public static boolean createDirectoryIfNotExists(Path path) {
    try {
      if (!Files.exists(path)) {
        Files.createDirectories(path);
        logger.info("创建目录: {}", path);
      }
      return true;
    } catch (IOException e) {
      logger.error("创建目录失败: {}, 错误: {}", path, e.getMessage());
      return false;
    }
  }

  /**
   * 检查目录是否为空
   * 
   * @param directory 目录路径
   * @return 是否为空
   */
  public static boolean isDirectoryEmpty(Path directory) {
    try {
      return !Files.list(directory).findAny().isPresent();
    } catch (IOException e) {
      logger.error("检查目录是否为空时出错: {}, 错误: {}", directory, e.getMessage());
      return true;
    }
  }
}
